FrameLib  0.1
Arbitrarily timed and sized frame-based DSP
FrameLib_FixedPoint.h
Go to the documentation of this file.
1 
2 #ifndef FRAMELIB_FIXEDPOINT_H
3 #define FRAMELIB_FIXEDPOINT_H
4 
5 #include <stdint.h>
6 #include <cmath>
7 #include <limits>
8 
9 // ************************************************************************************** //
10 
11 // FL_SP
12 
13 // This is a minimal class for super precision that aids the calculation of division in fixed point (giving added precision where needed)
14 
15 struct FL_SP
16 {
17  // Constructors
18 
19  FL_SP() {}
20  FL_SP(uint64_t a, uint64_t b, uint64_t c) : mInt(a), mFracHi(b), mFracLo(c) {}
21 
22  // Get Components
23 
24  uint64_t intVal() const { return mInt; }
25  uint64_t fracHiVal() const { return mFracHi; }
26  uint64_t fracLoVal() const { return mFracLo; }
27 
28  // Necessary Operations
29 
30  friend FL_SP qMul(const FL_SP& a, const uint64_t& intVal, const uint64_t& fracVal);
31  friend FL_SP operator * (const FL_SP& a, const FL_SP& b);
32  friend FL_SP twoMinus(const FL_SP& b);
33 
34 private:
35 
36  uint64_t mInt;
37  uint64_t mFracHi;
38  uint64_t mFracLo;
39 };
40 
41 // ************************************************************************************** //
42 
43 // FL_FP
44 
45 // This class provides a very high precision fixed point format for dealing with time
46 
47 class FL_FP
48 {
49 
50 public:
51 
52  // Constructors
53 
54  FL_FP() : mInt(0U), mFrac(0U) {}
55  FL_FP(uint64_t a, uint64_t b) : mInt(a), mFrac(b) {}
56  FL_FP(const FL_SP& val);
57  FL_FP(const double& val);
58 
59  // Int and Fract
60 
61  uint64_t intVal() { return mInt; }
62  uint64_t fracVal() { return mFrac; }
63 
64  // Absolute value
65 
66  friend bool nonZeroPositive(const FL_FP& a) { return a.mInt | a.mFrac; }
67 
68  // Comparison operators (N.B. - it is faster to avoid branching using bit rather logical operators)
69 
70  friend bool operator == (const FL_FP& a, const FL_FP& b) { return (a.mInt == b.mInt & a.mFrac == b.mFrac); }
71 
72  friend bool operator < (const FL_FP& a, const FL_FP& b) { return ((a.mInt < b.mInt) | (a.mInt == b.mInt & a.mFrac < b.mFrac)); }
73  friend bool operator > (const FL_FP& a, const FL_FP& b) { return ((a.mInt > b.mInt) | (a.mInt == b.mInt & a.mFrac > b.mFrac)); }
74  friend bool operator <= (const FL_FP& a, const FL_FP& b) { return !(a > b); }
75  friend bool operator >= (const FL_FP& a, const FL_FP& b) { return !(a < b); }
76 
77  // Zero Test
78 
79  friend bool operator ! ( const FL_FP& b) { return !b.mInt && !b.mFrac; }
80 
81  // Arithmetic Operators
82 
83  friend FL_FP operator + (const FL_FP& a, const FL_FP& b);
84  friend FL_FP operator - (const FL_FP& a, const FL_FP& b);
85  friend FL_FP operator * (const FL_FP& a, const FL_FP& b);
86  friend FL_FP operator / (const FL_FP& a, const FL_FP& b);
87 
88  // Arithmetic Operators with Assignment
89 
90  FL_FP& operator += (const FL_FP& b)
91  {
92  *this = *this + b;
93  return *this;
94  }
95 
96  FL_FP& operator -= (const FL_FP& b)
97  {
98  *this = *this - b;
99  return *this;
100  }
101 
102  FL_FP& operator *= (const FL_FP& b)
103  {
104  *this = *this * b;
105  return *this;
106  }
107 
108  FL_FP& operator /= (const FL_FP& b)
109  {
110  *this = *this / b;
111  return *this;
112  }
113 
114  // Increment / Decrement Operatiors
115 
116  FL_FP& operator ++ ()
117  {
118  if (++mFrac == uint64_t(0U))
119  ++mInt;
120 
121  return *this;
122  }
123 
124  FL_FP& operator ++ (int)
125  {
126  FL_FP& result = *this;
127  operator++();
128  return result;
129  }
130 
131  FL_FP& operator -- ()
132  {
133  if (mFrac-- == uint64_t(0U))
134  --mInt;
135 
136  return *this;
137  }
138 
139  FL_FP& operator -- (int)
140  {
141  FL_FP& result = *this;
142  operator--();
143  return result;
144  }
145 
146  // Support for operators using doubles
147 
148  // Conversion
149 
150  operator double() const { return ((double) mInt) + ((double) mFrac / 18446744073709551616.0); }
151 
152  FL_FP& operator = (const double& a)
153  {
154  *this = FL_FP(a);
155  return *this;
156  }
157 
158  // Comparison
159 
160  friend bool operator == (const FL_FP& a, const double& b) { return a == FL_FP(b); }
161  friend bool operator == (const double& a, const FL_FP& b) { return FL_FP(a) == b; }
162 
163  friend bool operator < (const FL_FP& a, const double& b) { return a < FL_FP(b); }
164  friend bool operator < (const double& a, const FL_FP& b) { return FL_FP(a) < b; }
165  friend bool operator > (const FL_FP& a, const double& b) { return a > FL_FP(b); }
166  friend bool operator > (const double& a, const FL_FP& b) { return FL_FP(a) > b; }
167  friend bool operator <= (const FL_FP& a, const double& b) { return a <= FL_FP(b); }
168  friend bool operator <= (const double& a, const FL_FP& b) { return FL_FP(a) <= b; }
169  friend bool operator >= (const FL_FP& a, const double& b) { return a >= FL_FP(b); }
170  friend bool operator >= (const double& a, const FL_FP& b) { return FL_FP(a) >= b; }
171 
172  // Arithmetic Operators
173 
174  friend FL_FP operator + (const FL_FP& a, const double& b) { return a + FL_FP(b); }
175  friend FL_FP operator + (const double& a, const FL_FP& b) { return FL_FP(a) + b; }
176  friend FL_FP operator - (const FL_FP& a, const double& b) { return a - FL_FP(b); }
177  friend FL_FP operator - (const double& a, const FL_FP& b) { return FL_FP(a) - b; }
178  friend FL_FP operator * (const FL_FP& a, const double& b) { return a * FL_FP(b); }
179  friend FL_FP operator * (const double& a, const FL_FP& b) { return FL_FP(a) * b; }
180  friend FL_FP operator / (const FL_FP& a, const double& b) { return a / FL_FP(b); }
181  friend FL_FP operator / (const double& a, const FL_FP& b) { return FL_FP(a) / b; }
182 
183  // Arithmetic Operators with Assignmnet
184 
185  FL_FP& operator += (const double& b) { return operator +=(FL_FP(b)); }
186  FL_FP& operator -= (const double& b) { return operator -=(FL_FP(b)); }
187  FL_FP& operator *= (const double& b) { return operator *=(FL_FP(b)); }
188  FL_FP& operator /= (const double& b) { return operator /=(FL_FP(b)); }
189 
190 private:
191 
192  uint64_t mInt;
193  uint64_t mFrac;
194 };
195 
196 // ************************************************************************************** //
197 
198 // Numeric Limits
199 
200 template <class T> struct FL_Limits
201 {
202  // N.B. there is basically no good value for smallest for a floating point unit, because all values will fail at some point before total overflow
203 
204  static T smallest() { return std::numeric_limits<T>::epsilon() * 65536.0; }
205 
206  static T largest()
207  {
208  if (std::numeric_limits<T>::has_infinity)
209  return std::numeric_limits<T>::infinity();
210  else
211  return std::numeric_limits<T>::max();
212  }
213 };
214 
215 template<> struct FL_Limits <FL_FP>
216 {
217  static FL_FP smallest() { return FL_FP(0,1); }
218  static FL_FP largest() { return FL_FP(std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max()); }
219 };
220 
221 // Double Helper Utility
222 
223 inline double nonZeroPositive(double& a) {return a > 0.0; }
224 
225 #endif
friend bool nonZeroPositive(const FL_FP &a)
Definition: FrameLib_FixedPoint.h:66
uint64_t fracLoVal() const
Definition: FrameLib_FixedPoint.h:26
static T largest()
Definition: FrameLib_FixedPoint.h:206
uint64_t fracHiVal() const
Definition: FrameLib_FixedPoint.h:25
FL_SP(uint64_t a, uint64_t b, uint64_t c)
Definition: FrameLib_FixedPoint.h:20
static T smallest()
Definition: FrameLib_FixedPoint.h:204
friend FL_SP operator*(const FL_SP &a, const FL_SP &b)
Definition: FrameLib_FixedPoint.cpp:126
Definition: FrameLib_FixedPoint.h:200
FL_FP operator/(const FL_FP &a, const FL_FP &b)
Definition: FrameLib_FixedPoint.cpp:384
uint64_t intVal()
Definition: FrameLib_FixedPoint.h:61
Definition: FrameLib_FixedPoint.h:47
FL_FP operator-(const FL_FP &a, const FL_FP &b)
Definition: FrameLib_FixedPoint.cpp:304
friend FL_SP twoMinus(const FL_SP &b)
Definition: FrameLib_FixedPoint.cpp:251
double nonZeroPositive(double &a)
Definition: FrameLib_FixedPoint.h:223
Definition: FrameLib_FixedPoint.h:15
FL_SP()
Definition: FrameLib_FixedPoint.h:19
static FL_FP largest()
Definition: FrameLib_FixedPoint.h:218
uint64_t fracVal()
Definition: FrameLib_FixedPoint.h:62
static FL_FP smallest()
Definition: FrameLib_FixedPoint.h:217
friend FL_SP qMul(const FL_SP &a, const uint64_t &intVal, const uint64_t &fracVal)
Definition: FrameLib_FixedPoint.cpp:31
uint64_t intVal() const
Definition: FrameLib_FixedPoint.h:24
FL_FP(uint64_t a, uint64_t b)
Definition: FrameLib_FixedPoint.h:55
FL_FP operator+(const FL_FP &a, const FL_FP &b)
Definition: FrameLib_FixedPoint.cpp:295
FL_FP()
Definition: FrameLib_FixedPoint.h:54